#include <examples.h>

#ifdef FSM
#include <algorithm/fsm.h>
#include <sheriffos.h>

class E1 : public os::Event {};

class E2 : public os::Event {};

class E3 : public os::Event {};

enum class S : uint8_t { A = 0, B, C, NULL_ } s{S::NULL_};

bool flag = false;
int es = 0;
bool ex = false;

class A final : public os::State {
    void onEnter() override { s = S::A; }
    void onExecute() override { fsm().react<E1>(); }
};

class B final : public os::State {
    void onEnter() override { s = S::B; }
};

class C final : public os::State {
    void onEnter() override { s = S::C; }
};

// clang-format off
os::StateMachine fsm {
    STATE(A) + EVENT(E1) >> BRANCH(
        CASE(flag == 0) >> STATE(B),
        CASE(flag == 1) >> STATE(C)
    ),
    STATE(B) + EVENT(E2) >> STATE(C),
    STATE(B) + EVENT(E3) >> STATE(A),
    STATE(C) + EVENT(E3) >> STATE(A)
};
// clang-format on

CREATE_THREAD_STATIC(run_fsm, 512, NULL, 5) {
    fsm.checkoutTo<A>();
    for (;;) {
        switch (es) {
            case 1:
                fsm.react<E1>();
                es = 0;
                break;
            case 2:
                fsm.react<E2>();
                es = 0;
                break;
            case 3:
                fsm.react<E3>();
                es = 0;
                break;
            default:
                break;
        }
        if (ex) fsm.execute(), ex = false;
        os::sleep(10_ms);
    }
}
#endif
